package com.dhcc.bpm.modules.scf.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dhcc.bpm.common.segmentId.LocalCacheIdGenerator;
import com.dhcc.bpm.modules.scf.dto.ScfContractInfoDTO;
import com.dhcc.bpm.modules.scf.entity.ScfContractInfo;
import com.dhcc.bpm.modules.scf.entity.ScfOperationLogInfo;
import com.dhcc.bpm.modules.scf.enumUtil.ScfOperationLogInfoEnum;
import com.dhcc.bpm.modules.scf.mapper.ScfContractInfoMapper;
import com.dhcc.bpm.modules.scf.mapper.ScfSubjectBasicInfoMapper;
import com.dhcc.bpm.modules.scf.service.IScfContractInfoService;
import com.dhcc.bpm.modules.scf.service.IScfFileAttachmentInfoService;
import com.dhcc.bpm.modules.scf.service.IScfOperationLogInfoService;
import com.dhcc.bpm.modules.scf.util.ExcelUtil;
import com.dhcc.bpm.modules.scf.util.OBSUtil;
import com.dhcc.bpm.modules.scf.vo.ScfContractInfoVO.ScfGetContractDetailsVO;
import com.dhcc.bpm.modules.scf.vo.ScfContractInfoVO.ScfGetContractListVO;
import com.dhcc.bpm.modules.scf.vo.ScfFileAttachmentInfoVO.ScfFileAttachmentInfoVO;
import com.dhcc.bpm.modules.scf.vo.ScfSubjectBasicInfoVO.ScfGetSubjectDetailsVO;
import com.dhcc.bpm.modules.system.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class ScfContractInfoServiceImpl extends ServiceImpl<ScfContractInfoMapper, ScfContractInfo> implements IScfContractInfoService {
    /**
     * 文件附件service接口
     */
    @Autowired
    private IScfFileAttachmentInfoService scfFileAttachmentInfoService;
    /**
     * id生成器
     */
    @Autowired
    private LocalCacheIdGenerator localCacheIdGenerator;
    /**
     * 操作日志service接口
     */
    @Autowired
    private IScfOperationLogInfoService scfOperationLogInfoService;
    /**
     * 主体信息服务service接口
     */
    @Autowired
    private ScfSubjectBasicInfoMapper scfSubjectBasicInfoMapper;
    /**
     * 用户service接口
     */
    @Autowired
    private IUserService userService;
    /**
     * OBS工具类
     */
    @Autowired
    private OBSUtil obsUtil;

    @Override
    public IPage<ScfGetContractListVO> selectScfContractInfoPage(IPage<ScfGetContractListVO> page, ScfContractInfoDTO scfContractInfo) {
        if(StringUtils.isNotEmpty( scfContractInfo.getNameA())  ){
            scfContractInfo.setNameA( scfContractInfo.getNameA().trim() );
        }
        if(StringUtils.isNotEmpty( scfContractInfo.getNameB())  ){
            scfContractInfo.setNameB( scfContractInfo.getNameB().trim() );
        }
        // 查询合同信息列表
        List<ScfGetContractListVO> scfContractInfoVOS = baseMapper.selectScfContractInfoPage(page, scfContractInfo);
        // 判断列表是否为空-如果不为空则将0000-00-00日期设置为长期有效
        if (scfContractInfoVOS.size() != 0) {
            for (ScfGetContractListVO contractInfo : scfContractInfoVOS) {
                if(contractInfo.getStartDate() ==null ){
                    contractInfo.setStartDate("0000-00-00" );
                }
                if(contractInfo.getEndDate() ==null ){
                    contractInfo.setEndDate("0000-00-00" );
                }
                // 获取合同生效日期
                if (contractInfo.getStartDate().equals("0000-00-00")) {
                    contractInfo.setStartDate("长期有效");
                }
                // 获取合同失效日期
                if (contractInfo.getEndDate().equals("0000-00-00")) {
                    contractInfo.setEndDate("长期有效");
                }
                // 获取合同金额
                if (contractInfo.getAmount().equals("0.00")) {
                    contractInfo.setAmount("无具体金额");
                }
                // 根据甲乙方主体编号查询主体名称
//                contractInfo.setNameA(scfSubjectBasicInfoMapper.selectNameBySubNum(contractInfo.getPartyANum()));
//                contractInfo.setNameB(scfSubjectBasicInfoMapper.selectNameBySubNum(contractInfo.getPartyBNum()));
            }
        }
        // 修改完数组列表返回列表数组
        return page.setRecords(scfContractInfoVOS);
    }

    /**
     * 查看合同详情
     *
     * @param scfContractInfo
     * @return
     */
    @Override
    public ScfGetContractDetailsVO getDetails(ScfContractInfoDTO scfContractInfo) {
        // 调用mapper接口查询合同详情
        ScfGetContractDetailsVO detail = baseMapper.getDetails(scfContractInfo.getRowId());
        if (detail != null) {
            // 获取合同生效日期
            if (detail.getStartDate()==null||  detail.getStartDate().equals("0000-00-00")) {
                detail.setStartDate("长期有效");
            }
            // 获取合同失效日期
            if (detail.getEndDate()==null || detail.getEndDate().equals("0000-00-00")) {
                detail.setEndDate("长期有效");
            }
            // 如果合同金额为0，则设置为无具体金额字符串
            // if (detail.getAmount().equals("0.00")) {
            //     detail.setAmount("无具体金额");
            // }
            // 根据甲乙方主体编号查询主体名称
            detail.setNameA(scfSubjectBasicInfoMapper.selectNameBySubNum(detail.getPartyANum()));
            detail.setNameB(scfSubjectBasicInfoMapper.selectNameBySubNum(detail.getPartyBNum()));
            // 获取甲方详细信息，补充至合同信息中
            ScfGetSubjectDetailsVO scfGetSubjectDetailsA = scfSubjectBasicInfoMapper.getDetails(detail.getPartyANum());
            if(scfGetSubjectDetailsA!=null){
                detail.setOpenBankA(scfGetSubjectDetailsA.getOpenBank());
                detail.setBankAccnoA(scfGetSubjectDetailsA.getBankAccno());
            }

            // 获取乙方详细信息，补充至合同信息中
            ScfGetSubjectDetailsVO ScfGetSubjectDetailsB = scfSubjectBasicInfoMapper.getDetails(detail.getPartyBNum());
            if(ScfGetSubjectDetailsB!=null){
                detail.setOpenBankB(ScfGetSubjectDetailsB.getOpenBank());
                detail.setBankAccnoB(ScfGetSubjectDetailsB.getBankAccno());
            }


            // 获取与文件附件表关联的id
            String rowId = detail.getRowId();
            // 查询关联的附件信息
            List<ScfFileAttachmentInfoVO> scfFileAttachmentInfoVOS = scfFileAttachmentInfoService.selectAllByAssociationId(rowId);
            // 创建一个list集合用于存放附件文件所以的文件rowId
            List<Long> ids = new ArrayList<>();
            if (scfFileAttachmentInfoVOS != null) {
                // 将附件信息存进scfGetContractDetailsVO里
                detail.setFileAttachmentInfoVOS(scfFileAttachmentInfoVOS);
                ids.add(Long.valueOf(detail.getRecorder()));
            }
            // 根据用户id查询用户名称，重新赋值登记人字段
            detail.setRecorder(userService.selectUserNameByIds(ids).get(0));
        }
        return detail;
    }

    /**
     * 新增合同信息
     *
     * @param scfContractInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveContractInfo(ScfContractInfoDTO scfContractInfo) throws Exception {
        // 首先判断该合同编号是否已存在表中，如果存在则认为该合同已录入
        if (baseMapper.selectRowIdByContractNum(scfContractInfo.getContractNum() ,scfContractInfo.getOrgCode()) != null) {
            throw new Exception("合同:" + scfContractInfo.getContractNum() + "已录入，请勿重复录入！");
        }
        // 生成年月日
        SimpleDateFormat date = new SimpleDateFormat("yyyyMMdd");
        String formatdate = date.format(new Date());
        // 生成时分秒
        SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
        String formTime = timeFormat.format(new Date());
        // 获取当前年月日时分秒
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
        String recordTime = dateFormat.format(calendar.getTime());
        if (StringUtils.isBlank(scfContractInfo.getContractNum())) {
            scfContractInfo.setContractNum("caigou" + formatdate + localCacheIdGenerator.nextId());
        }
        // 如果未填写合同金额则默认设置为0.00
        if (scfContractInfo.getAmount() == null) {
            scfContractInfo.setAmount(BigDecimal.valueOf(0.00));
        }
        // 生成ROW_ID
        String rowId = "HT" + localCacheIdGenerator.nextId() + formTime;
        // 设置字段
        scfContractInfo.setRowId(rowId);
        scfContractInfo.setRecordDate(formatdate);
        scfContractInfo.setRecordTime(formTime);
        boolean isSave = save(scfContractInfo);
        // 设置合同文件存放路径
        String path = "HT" + "/" + rowId + "/";
        // 获取文件附件表中，文件对应的ROW_ID
        List<String> fileRowIds = scfContractInfo.getRowIds();
        // 判断是否上传了文件
        if (fileRowIds != null) {
            if (!fileRowIds.isEmpty()) {
                if (isSave) {
                    for (String fileRowId : fileRowIds) {
                        // 根据文件id获取文件的临时objectKey
                        String objectKeyOfTemp = scfFileAttachmentInfoService.getFilePath(fileRowId,null);
                        // 截取文件的名称
                        String extractFileName = obsUtil.extractFileName(objectKeyOfTemp);
                        // 拼接正式的objectKey
                        String objectKey = path + extractFileName;
                        // 调用obs将文件从临时目录复制到正式目录
                        obsUtil.copyFile(objectKey, objectKeyOfTemp);
                        scfFileAttachmentInfoService.updateFilePath(fileRowId, objectKey);
                    }
                }
                scfFileAttachmentInfoService.batchUpdateField(fileRowIds, rowId);
            }
        }
        // 记录操作日志
        ScfOperationLogInfo scfOperationLogInfo = new ScfOperationLogInfo();
        // 根据用户id查询用户名称，重新赋值登记人字段
        List<Long> ids = new ArrayList<>();
        ids.add(Long.valueOf(scfContractInfo.getRecorder()));
        scfOperationLogInfo.setRecorder(userService.selectUserNameByIds(ids).get(0));
        scfOperationLogInfo.setOperationModule(ScfOperationLogInfoEnum.CONTRACT.getOperation());
        scfOperationLogInfo.setOperationFunction("合同信息维护");
        scfOperationLogInfo.setOperationType(ScfOperationLogInfoEnum.ADD.getOperation());
        scfOperationLogInfo.setOperationContent("新增一条合同信息，合同编号：" + scfContractInfo.getContractNum());
        scfOperationLogInfo.setRecordDate(recordTime);
        // 判断合同信息是否保存成功--成功则保存操作日志
        if (isSave) {
            scfOperationLogInfoService.saveOperationLogInfo(scfOperationLogInfo);
        }
        return isSave;
    }

    /**
     * 导入合同信息
     *
     * @param scfContractInfos
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int bachSaveContractInfo(List<ScfContractInfo> scfContractInfos, String operatorId) {
        // 日志集合
        List<ScfOperationLogInfo> scfOperationLogInfos = new ArrayList<>();
        // 合同集合
        List<ScfContractInfo> scfContractInfosNew = new ArrayList<>();
        for (ScfContractInfo scfContractInfo : scfContractInfos) {
            // 设置登记人ID
            scfContractInfo.setRecorder(operatorId);
            // 合同类型
            String contractType = scfContractInfo.getContractType();
            if (contractType != null) {
                switch (contractType) {
                    case "供销合同":
                        // 执行与 value1 匹配的代码块
                        scfContractInfo.setContractType("2");
                        break;
                    case "采购合同":
                        // 执行与 value2 匹配的代码块
                        scfContractInfo.setContractType("1");
                        break;
                    // 可以有更多的 case 分支
                    default:
                        // 如果没有任何 case 匹配，则执行 default 代码块
                        break;
                }
            }
            // 设置正确的甲乙编号
            scfContractInfo.setPartyANum(scfSubjectBasicInfoMapper.selectSubNumBySubName(scfContractInfo.getPartyANum()));
            scfContractInfo.setPartyBNum(scfSubjectBasicInfoMapper.selectSubNumBySubName(scfContractInfo.getPartyBNum()));
            // 补充字段
            // 生成年月日
            SimpleDateFormat date = new SimpleDateFormat("yyyyMMdd");
            String formatdate = date.format(new Date());
            // 生成时分秒
            SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
            String formTime = timeFormat.format(new Date());
            // 获取当前年月日时分秒
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
            String recordTime = dateFormat.format(calendar.getTime());
            if (StringUtils.isBlank(scfContractInfo.getContractNum())) {
                scfContractInfo.setContractNum("caigou" + formatdate + localCacheIdGenerator.nextId());
            }
            // 如果未填写合同金额则默认设置为0.00
            if (scfContractInfo.getAmount() == null) {
                scfContractInfo.setAmount(BigDecimal.valueOf(0.00));
            }
            // 生成ROW_ID
            String rowId = "HT" + localCacheIdGenerator.nextId() + formTime;
            // 设置字段
            scfContractInfo.setRowId(rowId);
            scfContractInfo.setRecordDate(formatdate);
            scfContractInfo.setRecordTime(formTime);
            // 首先判断该合同编号是否已存在表中，如果存在则认为该合同已录入
            if (baseMapper.selectRowIdByContractNum(scfContractInfo.getContractNum() ,scfContractInfo.getOrgCode()) == null     ) {
                scfContractInfosNew.add(scfContractInfo);
                // 记录操作日志
                ScfOperationLogInfo scfOperationLogInfo = new ScfOperationLogInfo();
                // 根据用户id查询用户名称，重新赋值登记人字段
                List<Long> ids = new ArrayList<>();
                ids.add(Long.valueOf(scfContractInfo.getRecorder()));
                scfOperationLogInfo.setRecorder(userService.selectUserNameByIds(ids).get(0));
                scfOperationLogInfo.setOperationModule(ScfOperationLogInfoEnum.CONTRACT.getOperation());
                scfOperationLogInfo.setOperationFunction("合同信息维护");
                scfOperationLogInfo.setOperationType(ScfOperationLogInfoEnum.ADD.getOperation());
                scfOperationLogInfo.setOperationContent("新增一条合同信息，合同编号：" + scfContractInfo.getContractNum());
                scfOperationLogInfo.setRecordDate(recordTime);
                scfOperationLogInfos.add(scfOperationLogInfo);
            }
        }
        boolean saveBatch = saveBatch(scfContractInfosNew);
        if (saveBatch) {
            scfOperationLogInfoService.bachSaveOperationLogInfo(scfOperationLogInfos);
        }
        return scfContractInfosNew.size();
    }

    /**
     * 更新合同信息
     *
     * @param scfContractInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateContractInfo(ScfContractInfoDTO scfContractInfo) {
        // 生成年月日
        SimpleDateFormat date = new SimpleDateFormat("yyyyMMdd");
        String formatdate = date.format(new Date());
        // 生成时分秒
        SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
        String formTime = timeFormat.format(new Date());
        // 获取当前年月日时分秒
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
        String recordTime = dateFormat.format(calendar.getTime());
        // 获取文件附件表中，文件对应的ROW_ID
        List<String> fileRowIds = scfContractInfo.getRowIds();
        if (fileRowIds != null) {
            if (!fileRowIds.isEmpty()) {
                String rowId = scfContractInfo.getRowId();
                // 设置合同文件存放路径
                String path = "HT" + "/" + rowId + "/";
                if (rowId != null) {
                    // 更新文件附件表--清楚旧的附件文件关联记录
                    scfFileAttachmentInfoService.updataFiledNull(rowId);
                    // 判断是否上传文件
                    scfFileAttachmentInfoService.batchUpdateField(fileRowIds, rowId);
                    for (String fileRowId : fileRowIds) {
                        // 根据文件id获取文件的临时objectKey
                        String objectKeyOfTemp = scfFileAttachmentInfoService.getFilePath(fileRowId,null);
                        // 截取文件的名称
                        String extractFileName = obsUtil.extractFileName(objectKeyOfTemp);
                        // 拼接正式的objectKey
                        String objectKey = path + extractFileName;
                        // 调用obs将文件从临时目录复制到正式目录
                        obsUtil.copyFile(objectKey, objectKeyOfTemp);
                        scfFileAttachmentInfoService.updateFilePath(fileRowId, objectKey);
                    }
                }
            }
        }
        // 如果未填写合同金额则默认设置为0.00
        if (scfContractInfo.getAmount() == null) {
            scfContractInfo.setAmount(BigDecimal.valueOf(0.00));
        }
        scfContractInfo.setRecordDate(formatdate);
        scfContractInfo.setRecordTime(formTime);
        // 更新合同信息记录
        boolean update = updateById(scfContractInfo);
        // 记录操作日志
        ScfOperationLogInfo scfOperationLogInfo = new ScfOperationLogInfo();
        // 根据用户id查询用户名称，重新赋值登记人字段
        List<Long> ids = new ArrayList<>();
        ids.add(Long.valueOf(scfContractInfo.getRecorder()));
        scfOperationLogInfo.setRecorder(userService.selectUserNameByIds(ids).get(0));
        scfOperationLogInfo.setOperationModule(ScfOperationLogInfoEnum.CONTRACT.getOperation());
        scfOperationLogInfo.setOperationFunction("合同信息维护");
        scfOperationLogInfo.setOperationType(ScfOperationLogInfoEnum.UPDATE.getOperation());
        scfOperationLogInfo.setOperationContent("更新一条合同信息，合同编号：" + scfContractInfo.getContractNum());
        scfOperationLogInfo.setRecordDate(recordTime);
        // 判断合同信息更新是否完成，如果成功则记录操作日志记录
        if (update) {
            scfOperationLogInfoService.saveOperationLogInfo(scfOperationLogInfo);
        }
        return update;
    }

    /**
     * 批量导入合同信息接口
     *
     * @param operatorId
     * @param file
     * @return
     * @throws IOException
     */
    @Override
    public List<ScfContractInfo> batchSaveContractInfo(String operatorId, MultipartFile file) throws IOException {
        // 获取文件的Base64编码
        byte[] fileBytes = file.getBytes();
        // 解析excel文件获取数据集合
        List<ScfContractInfo> scfContractInfos = ExcelUtil.readExcel(fileBytes, ScfContractInfo.class, "合同信息", 3);
        log.info("数据集合为：{}", scfContractInfos);
        return scfContractInfos;
    }

    @Override
    public Boolean deleteByIds(String[] ids) {
        return this.baseMapper.deleteByIds(ids);
    }
}
